use rand::Rng;
use std::ffi::OsString;
use std::sync::{Arc, Mutex};
use std::thread;
use std::time::Duration;
use windows_service::define_windows_service;
use windows_service::service::{
    ServiceControl, ServiceControlAccept, ServiceErrorControl, ServiceExitCode, ServiceInfo,
    ServiceStartType, ServiceState, ServiceStatus, ServiceType,
};
use windows_service::service_control_handler;
use windows_service::service_control_handler::ServiceControlHandlerResult;
use windows_service::service_dispatcher;
mod bochu_monitor;
use crate::bochu_monitor::{
    gather_system_info, scan_processes, upload_shutdown_start_times, upload_software_info,
    upload_system_process_info, write_info_to_json,
};

use reqwest;
use serde_json::{json};
use tokio;
use winapi::um::wincon::GetConsoleWindow;
use winapi::um::winuser::{ShowWindow, SW_HIDE};
// For async tasks

const SERVICE_NAME: &str = "WIN_OCS_SERVICE";
const SERVICE_DISPLAY_NAME: &str = "WIN_OCS_SERVICE";

// 定义Windows服务
define_windows_service!(ffi_service_main, my_service_main);

// 服务主入口
fn my_service_main(_arguments: Vec<OsString>) {
    // Create a runtime and run the async function inside it
    let rt = tokio::runtime::Runtime::new().unwrap();
    if let Err(e) = rt.block_on(run_service()) {
        eprintln!("服务错误: {:?}", e);
    }



}

// 运行服务的逻辑
async fn run_service() -> windows_service::Result<()> {
    let running_flag = Arc::new(Mutex::new(true));

    // 注册服务控制事件处理器
    let status_handle = service_control_handler::register(SERVICE_NAME, {
        let running_flag = running_flag.clone();
        move |control_event| {
            match control_event {
                ServiceControl::Interrogate => ServiceControlHandlerResult::NoError,
                ServiceControl::Stop => {
                    println!("收到停止信号，服务将停止...");
                    let mut running = running_flag.lock().unwrap();
                    *running = false; // 修改运行标志
                    ServiceControlHandlerResult::NoError
                }
                _ => ServiceControlHandlerResult::NotImplemented,
            }
        }
    })?;

    // 设置服务状态为运行中
    status_handle.set_service_status(ServiceStatus {
        service_type: ServiceType::OWN_PROCESS,
        current_state: ServiceState::Running,
        controls_accepted: ServiceControlAccept::STOP, // 允许停止
        exit_code: ServiceExitCode::Win32(0),
        checkpoint: 0,
        wait_hint: Duration::default(),
        process_id: None,
    })?;

    // 运行定时任务
    while *running_flag.lock().unwrap() {
        // 及时检查停止标志
        if !*running_flag.lock().unwrap() {
            break;
        }
        // 获取系统进程信息并写入文件
        let sys_info = gather_system_info();
        let processes = scan_processes();

        // 组织数据，确保符合你提供的 JSON 格式
        let json_data = json!({
            "deviceInfo": [
                sys_info
            ],
            "process": processes
        });

        // 将 JSON 写入文件
        match write_info_to_json(&json_data) {
            Ok(_) => {
                println!("系统信息和进程信息已成功写入文件！");
            }
            Err(e) => eprintln!("写入文件时发生错误: {}", e),
        }

        // 执行HTTP上传任务
        if let Err(e) = upload_system_process_info().await {
            eprintln!("上传系统信息失败: {}", e);
        }

        // 执行上传软件信息任务（不再依赖进程信息）
        if let Err(e) = upload_software_info().await {
            eprintln!("上传软件信息失败: {}", e);
        }

        // 执行上传开关机，锁屏解锁数据任务
        if let Err(e) = upload_shutdown_start_times().await {
            eprintln!("上传开机关机，锁屏解锁信息失败: {}", e);
        }

        // 生成30分钟左右的随机时间
        let mut rng = rand::thread_rng();
        let random_seconds = rng.gen_range(1500..=2100);

        for _ in 0..random_seconds {
            tokio::time::sleep(Duration::from_secs(1)).await;

            // 每秒钟检查一次停止标志
            if !*running_flag.lock().unwrap() {
                break;
            }
        }
    }

    // 设置服务状态为停止
    status_handle.set_service_status(ServiceStatus {
        service_type: ServiceType::OWN_PROCESS,
        current_state: ServiceState::Stopped,
        controls_accepted: ServiceControlAccept::STOP, // 停止后不再接受控制
        exit_code: ServiceExitCode::Win32(0),
        checkpoint: 0,
        wait_hint: Duration::default(),
        process_id: None,
    })?;

    Ok(())
}

// 安装服务
fn install_service() -> windows_service::Result<()> {
    use std::env;
    use windows_service::service_manager::{ServiceManager, ServiceManagerAccess};
    let manager =
        ServiceManager::local_computer(None::<&str>, ServiceManagerAccess::CREATE_SERVICE)?;

    let service_binary_path = env::current_exe().unwrap();
    let service_info = ServiceInfo {
        name: SERVICE_NAME.into(),
        display_name: SERVICE_DISPLAY_NAME.into(),
        service_type: ServiceType::OWN_PROCESS,
        start_type: ServiceStartType::AutoStart, // 设置为自动启动
        error_control: ServiceErrorControl::Normal,
        executable_path: service_binary_path,
        launch_arguments: vec![],
        dependencies: vec![],
        account_name: None,
        account_password: None,
    };

    manager.create_service(
        &service_info,
        windows_service::service::ServiceAccess::CHANGE_CONFIG
            | windows_service::service::ServiceAccess::START,
    )?;
    Ok(())
}

// 检查服务是否已安装
fn is_service_installed(service_name: &str) -> bool {
    let manager = windows_service::service_manager::ServiceManager::local_computer(
        None::<&str>,
        windows_service::service_manager::ServiceManagerAccess::CONNECT,
    )
        .unwrap();
    manager
        .open_service(
            service_name,
            windows_service::service::ServiceAccess::QUERY_STATUS,
        )
        .is_ok()
}

fn hide_console_window() {
    unsafe {
        let hwnd = GetConsoleWindow();
        if !hwnd.is_null() {
            ShowWindow(hwnd, SW_HIDE);
        }
    }
}

fn main() -> windows_service::Result<()> {
    // 检查并安装服务
    if !is_service_installed(SERVICE_NAME) {
        install_service()?;
        println!("服务安装成功.");
    } else {
        println!("服务已安装.");
    }

    // 启动服务
    match service_dispatcher::start(SERVICE_NAME, ffi_service_main) {
        Ok(_) => println!("服务启动成功."),
        Err(e) => eprintln!("服务启动失败: {:?}", e),
    }

    Ok(())
}
